/*
 *  hackds/course_design/voldemort_language/src/translate.c 
 *
 *  (C) 2011 Harry Wei
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdint.h>

#include "../include/vl.h"

int
tran_vol(char *vol_lan, struct rule *regu, int r_counter)
{
	int i = 0;
	int l_bracket = (int) 0;
	int r_bracket = (int) 0;
	
	fprintf(stdout, "What about Voldemort Language: ");
	fscanf(stdin, "%s", vol_lan);
	while (vol_lan[i]) {
		if ('(' == vol_lan[i]) {
			l_bracket += 1;
			i += 1;
			continue;
		} else if (')' == vol_lan[i]) {
			r_bracket += 1;
			i += 1;
			continue;
		} else {
			i += 1;
			continue;
		}
	}
	if (l_bracket != r_bracket) {
		fprintf(stderr, "This is not Voldemort Language!\n");
		return 1;
	}
	if (take_bracket(vol_lan)) {
		return 1;
	}
	if (replace_uppers(vol_lan, regu, r_counter)) {
		return 1;
	}
	return 0;
}

int 
take_bracket(char *vol_lan)
{
	int m;
	int i = 0;
	int j;
	int temp;
	int k;
	int counter = 0;
	int check = 0;
	int last = 0;
	int flag = 0;
	char ch;
	char *dup = NULL;
	char *exe = dup;
	char exch[BUF];
	struct stack *s = NULL;

	s = (struct stack *)malloc(sizeof(struct stack));
	if (!s) {
		fprintf(stderr, "Allocate Error!\n");
		return 1;
	} 
	init(s);
	dup = (char *)malloc(sizeof(char) * BUF);
	if (!dup) {
		fprintf(stderr, "Allocate Error!\n");
		return 1;
	}
	while (vol_lan[i]) {
		dup[i] = vol_lan[i];
		if ('(' == vol_lan[i])
			counter += 1;
		i += 1;
	}
	if (!counter)
		return 0;
	for (temp = 0; temp < i; temp++) {
		if ('(' == vol_lan[temp]) {
			k = 1;
			check += 1;
			ch = vol_lan[temp + 1];
			temp = temp + 1;
			continue;
		}
		if (check == counter) {
			if (')' == vol_lan[temp]) {
				k += 1;
				break;
			}
			k += 1;
			push(s, vol_lan[temp]);
		}
	}
	temp = 0;
	while (s->next) {
		s = s->next;
		exch[temp] = ch;
		temp += 1;
//		pop(s, &exch[temp]); /* XXX BUG Here XXX */
		exch[temp] = s->ch;
		temp += 1;
//		break;
	}
	exch[temp] = ch;
	exch[temp + 1] = '\0';
	for (counter = 0; counter < i; counter++) {
		if ('(' == vol_lan[counter])
			last += 1;
		if (last == check && 0 == flag) {
			m = counter;
			for (j = 0; j < temp + 1; j++) {
				vol_lan[m] = exch[j];
				m += 1;
			}
			flag = 1;
			counter += k + 1;
		}
		if (1 == flag) {
			vol_lan[m] = dup[counter];
			m += 1;
		}
	}
	vol_lan[m] = '\0';
	return take_bracket(vol_lan);
}

int replace_uppers(char *vol_lan, struct rule *regu, int r_counter)
{
	int i = 0;
	int rem;
	int temp;
	int counter = 0;
	int check = 0;
	char *dup = NULL;

	dup = (char *)malloc(sizeof(char) * BUF);
	if (!dup) {
		fprintf(stderr, "Allocate Error!\n");
		return 1;
	}
	while (vol_lan[i]) {
		if ('A' <= vol_lan[i] &&
			vol_lan[i] <= 'Z')
			check += 1;
		dup[i] = vol_lan[i];
		i += 1;
	}
	if (!check) 
		return 0;
	dup[i] = '\0';
#if DEBUG == 1
	for (i = 0; i < r_counter; i++) {
		printf("%c\n", regu[i].upper_ch);
		printf("%s\n", regu[i].reg);
		printf("%d\n", strlen(regu[i].reg));
	}
#endif
	while (vol_lan[counter]) {
		if (vol_lan[counter] >= 'A' &&
			vol_lan[counter] <= 'Z') {
			rem = counter;
			for (i = 0; i < r_counter; i++) {
				if (vol_lan[counter] == regu[i].upper_ch) {
					for (temp = 0; temp < strlen(regu[i].reg); temp++) {
						vol_lan[rem] = regu[i].reg[temp];
						rem += 1;
					}
					counter += 1; 
					break;
				}
			}

			while (dup[counter]) {
				vol_lan[rem] = dup[counter];
				rem += 1;
				counter += 1;
			}
			break;
		} else {
			counter += 1;
			continue;
		}
	}
	return replace_uppers(vol_lan, regu, r_counter);
}
